﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ElevatorLib
{
    /// <summary>
    /// 客流生成的抽象类
    /// </summary>
    public abstract class AbstractPersonCreator
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public AbstractPersonCreator()
        {
            url = "Person.dat";
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="_url">生成文件的路径</param>
        public AbstractPersonCreator(string _url)
        {
            url = _url;
        }

        /// <summary>
        /// 作者
        /// </summary>
        public string Author
        {
            get
            {
                return author;
            }
        }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description
        {
            get
            {
                return description;
            }
        }

        /// <summary>
        /// 客流文件名称
        /// </summary>
        public string Name
        {
            get
            {
                return name;
            }
        }

        #region Properties
        /// <summary>
        /// 生成客流数据的路径
        /// </summary>
        private string url;
        /// <summary>
        /// 输出流
        /// </summary>
        private StreamWriter outputSteam;
        /// <summary>
        /// 随机数
        /// </summary>
        protected Random rnd = new Random(DateTime.Now.Millisecond);
        /// <summary>
        /// 客流文件名称
        /// </summary>
        protected string name;
        /// <summary>
        /// 作者
        /// </summary>
        protected string author;
        /// <summary>
        /// 描述
        /// </summary>
        protected string description;
        #endregion

        #region Function
        /// <summary>
        /// 输出客流数据
        /// Output the passenger flow data
        /// </summary>
        /// <param name="p"></param>
        protected void Output(Person p)
        {
            outputSteam.WriteLine(String.Format("{0:f}", p.arriveTime) + ":"
                + p.originFloor + ":" + p.targetFloor + ":"
                + String.Format("{0:f}", p.timeIn) + ":"
                + String.Format("{0:f}", p.timeOut) + ":"
                + String.Format("{0:f}", p.requestDelay));
            outputSteam.Flush();
        }
        /// <summary>
        /// 创建客流数据文件
        /// </summary>
        public void Create()
        {
            try
            {
                outputSteam = File.CreateText(url);
            }
            catch (Exception e)
            {
                outputSteam = File.CreateText("Person.dat");
                throw new Exception(e.Message);
            }
            outputSteam.WriteLine("NAME:" + name);
            outputSteam.WriteLine("AUTHOR:" + author);
            outputSteam.WriteLine("DESCRIPTIONG:" + description);
            outputSteam.WriteLine("DATE:" + DateTime.Now.ToLongDateString());
            outputSteam.WriteLine("CONTEXT----ArriveTime:OriginFloor:TargetFloor:In:Out:Delay");

            CreatePerson();

            outputSteam.WriteLine("EOF");
            outputSteam.Close();
        }
        #endregion

        /// <summary>
        /// 创建具体客流抽象函数
        /// </summary>
        protected abstract void CreatePerson();

        /// <summary>
        /// 读取客流文件
        /// </summary>
        /// <param name="path">文件地址</param>
        public virtual bool Read(string path)
        {
            if (path == null)
            {
                path = "Person.dat";
            }
            
            try
            {
                FileStream file = new FileStream(path, FileMode.Open);
                StreamReader sr = new StreamReader(file, System.Text.Encoding.GetEncoding("UTF-8"));
                string data;
                string[] dataTmp;
                SimulationEngine.simData = new Queue<Person>();

                #region 读取前面5行信息
                data = sr.ReadLine();
                data = sr.ReadLine();
                data = sr.ReadLine();
                data = sr.ReadLine();
                data = sr.ReadLine();
                #endregion 

                while ((data = sr.ReadLine()) != "EOF")
                {
                    dataTmp = data.Split(':');
                    Person p = new Person();
                    p.arriveTime = Convert.ToDouble(dataTmp[0]);
                    p.originFloor = Convert.ToInt32(dataTmp[1]);
                    p.targetFloor = Convert.ToInt32(dataTmp[2]);
                    p.timeIn = Convert.ToDouble(dataTmp[3]);
                    p.timeOut = Convert.ToDouble(dataTmp[4]);
                    p.requestDelay = Convert.ToDouble(dataTmp[5]);
                    p.waitTime = double.PositiveInfinity;
                    p.servTime = double.PositiveInfinity;
                    SimulationEngine.simData.Enqueue(p);
                }
                sr.Close();
            }
            catch
            {
                return false;
            }
            return true;
        }
    }
}
